//
// Created by yanhai on 2021/11/5.
//

#pragma once

#include "spare_queue.h"

class SpareQueueProxy {
public:
    typedef SpareQueue::value_type value_type;
    typedef SpareQueue::length_type length_type;

    SpareQueueProxy(unsigned int prealloc,
                    const std::function<value_type *()> &NewNode,
                    const std::function<void(value_type *)> &FreeNode)
            : prealloc(prealloc),
              NewNode(NewNode),
              FreeNode(FreeNode)
    {
        spareQueue = new SpareQueue();
    }

    ~SpareQueueProxy()
    {
        Clear();
        delete spareQueue;
    }

    // 根据预申请值向队列中填充节点
    bool Prealloc();

    void Clear();   // 清除所有节点

    /** \brief Make sure we have enough spare flows.
     *
     *  Enforce the prealloc parameter, so keep at least prealloc flows in the
     *  spare queue and free flows going over the limit.
     *
     *  \retval true if the queue was properly updated (or if it already was in good shape)
     *  \retval false otherwise.
     */
    bool Update();

    // 代理spare queue的成员函数

    // 将node放入队列
    void Enqueue(value_type *node);

    // 从队列中取出node，有可能为空
    value_type *Dequeue();

    length_type Len() const;

private:
    const std::function<value_type *()> &NewNode;
    const std::function<void(value_type *)> &FreeNode;

    SpareQueue *spareQueue;
    unsigned int prealloc;  // 队列预申请大小
};


// proxy function (inline)

inline void SpareQueueProxy::Enqueue(value_type *node)
{
    spareQueue->Enqueue(node);
}

inline SpareQueueProxy::value_type *SpareQueueProxy::Dequeue()
{
    return spareQueue->Dequeue();
}

inline SpareQueueProxy::length_type SpareQueueProxy::Len() const
{
    return spareQueue->Len();
}
